from Common.BaseView import BaseView, Blueprint, Api, request, check_permission
from Modules.sys_account.model import db, AccountModel, RoleModel
from Modules.sys_account.form import AccountDeleteForm, AccountPutForm, RolePostForm, RolePutForm, RoleDeleteForm
from Modules.sys_module.model import ModuleModel, ActionModel
from Modules.sys_log.view import system_log

account_bp = Blueprint('account', __name__, url_prefix='/api', cli_group=None)
api = Api(account_bp)


def _create_user():
    account = input('请输入帐号：')
    try:
        data = AccountModel.query.filter_by(username=account).first()
        if data is not None:
            print('帐号已存在！')
            return
    except Exception as err:
        print('创建帐号失败！请重新尝试。原因：%s' % err)
        return

    password = input('请输入密码：')
    confirm = input('请确认密码：')

    while password != confirm:
        print('创建失败，两次输入密码不一致！请重新输入！')
        password = input('请输入密码：')
        confirm = input('请确认密码：')

    try:
        new_account = AccountModel({'username': account, 'password': password})

        db.session.add(new_account)
        db.session.commit()

        print('帐号:{account}创建成功;ID:{id}'.format(account=account, id=new_account.id))

    except Exception as err:
        print('创建帐号失败！请重新尝试。原因：%s' % err)
        return


@account_bp.cli.command('create-user')
def create_user():
    print('开始创建帐号：')
    _create_user()


class AccountView(BaseView):
    method_decorators = [check_permission, system_log]

    def get(self):
        try:
            # 帐号列表
            data_list = self.to_array(AccountModel.query.all())
            for item in data_list:
                del item['_password']
            return self.result('0x00010', data=data_list)
        except Exception as error:
            return self.result('0x00011', data='%s' % error)

    def post(self):
        try:
            pass
        except Exception as error:
            return self.result('0x00013', data='%s' % error)

    def put(self):
        try:
            form = AccountPutForm()
            if form.validate_on_submit() is False:
                return self.result('0x00017')
            account = AccountModel.query.filter_by(id=form.data['id']).first()
            if account is None:
                return self.result('0x00017')
            account.password = form.data['newpwd']
            db.session.commit()
            return self.result('0x00016')
        except Exception as error:

            return self.result('0x00017', data='%s' % error)

    def delete(self):
        try:
            form = AccountDeleteForm()
            if form.validate_on_submit() is False:
                return self.result('0x00019')
            account = AccountModel.query.filter_by(id=form.data['id']).first()
            if account is None:
                return self.result('0x00019')
            account.status = not account.status
            db.session.commit()
            return self.result('0x00018')
        except Exception as error:
            return self.result('0x00019', data='%s' % error)


def create_module_tree(result, modules):
    if modules.pid is None:
        result.append({'id': modules.id, 'name': modules.name, 'type': modules.type})
        return
    for r in result:
        if r['id'] == modules.pid:
            if 'children' in r:
                r['children'].append({'id': modules.id, 'name': modules.name, 'type': modules.type})
            else:
                r['children'] = [{'id': modules.id, 'name': modules.name, 'type': modules.type}]
        elif 'children' in r:
            create_module_tree(r['children'], modules)


class RoleView(BaseView):
    method_decorators = [check_permission, system_log]

    def get(self):
        try:
            scope = request.args.get('scope')
            if scope == 'role':
                return self.result('0x00010', data=self.to_array(RoleModel.query.all()))
            if scope == 'account':
                result_data = {'all': [], 'sel': []}
                accounts = self.to_array(AccountModel.query.all())
                for account in accounts:
                    result_data['all'].append({'key': account['id'], 'label': account['username']})
                role_accounts = self.to_array(RoleModel.query.filter_by(id=request.args.get('id')).first().accounts)
                for account in role_accounts:
                    result_data['sel'].append(account['id'])
                return self.result('0x00010', data=result_data)
            if scope == 'module':
                modules = db.session.query(ModuleModel.id, ModuleModel.pid, ModuleModel.name, ModuleModel.type).all()
                result = []
                for item in modules:
                    create_module_tree(result, item)
                return self.result('0x00010', data=result)
            if scope == 'action':
                result_data = {'all': [], 'sel': []}
                # 全部功能
                module = ModuleModel.query.filter_by(id=request.args.get('module_id')).first()
                for item in module.actions:
                    result_data['all'].append({'id': item.id, 'name': item.name})
                # 角色拥有的功能
                role = RoleModel.query.filter_by(id=request.args.get('role_id')).first()
                hassel_actions = role.actions.filter_by(module_id=request.args.get('module_id')).all()
                for item in hassel_actions:
                    result_data['sel'].append({'id': item.id, 'name': item.name})
                return self.result('0x00010', data=result_data)
        except Exception as error:

            return self.result('0x00011', data='%s' % error)

    def post(self):
        try:
            form = RolePostForm()
            if form.validate_on_submit() is False:
                return self.result('0x00013')
            data_ins = RoleModel(form.data)
            db.session.add(data_ins)
            db.session.commit()
            return self.result('0x00012')
        except Exception as error:
            return self.result('0x00013', data='%s' % error)

    def put(self):
        try:
            scope = request.json['scope']
            if scope == 'role':
                form = RolePutForm()
                if not form.validate_on_submit():
                    return
                data = form.data
                del data['csrf_token']
                RoleModel.query.filter_by(id=form.data['id']).update(data)
                db.session.commit()
                return self.result('0x00016')
            if scope == 'account':
                account_list = request.json['select']
                role = RoleModel.query.filter_by(id=request.json['id']).first()
                accounts = AccountModel.query.filter(AccountModel.id.in_(account_list)).all()
                role.accounts = accounts
                db.session.commit()
                return self.result('0x00016')
            if scope == 'action':
                role = RoleModel.query.filter_by(id=request.json['role_id']).first()
                cursel_actions = ActionModel.query.filter(ActionModel.id.in_(request.json['actions'])).all()
                hassel_actions = role.actions.filter_by(module_id=request.json['module_id']).all()
                for item in hassel_actions:
                    role.actions.remove(item)
                db.session.commit()
                role.actions.extend(cursel_actions)
                db.session.commit()
                return self.result('0x00016')
        except Exception as error:
            print(error)
            return self.result('0x00017', data='%s' % error)

    def delete(self):
        try:
            form = RoleDeleteForm()
            if not form.validate_on_submit():
                return self.result('0x00015')
            RoleModel.query.filter_by(id=form.data['id']).delete()
            db.session.commit()
            return self.result('0x00014')
        except Exception as error:
            return self.result('0x00015', data='%s' % error)


api.add_resource(AccountView, '/account')
api.add_resource(RoleView, '/account/role')
